﻿#region Usings
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

using BK.Financisto;

using Lib.Data.CSV;
using Lib.Utils.Collections;
using Lib.Utils.StrUtils;
using Lib.Utils.StrUtils.FromStringConverter;
using Lib.Utils.Validation;
#endregion

namespace BK.Model
{
    public class FinancistoExpense : BaseBkEntity, ICsvEntity, ICommonExpense, IImportedEntity
    {
        #region Constants
        private const string MESSAGE_TEMPLATE = "Колонка '{0}' має бути {1}";
        private const string NON_EMPTY_FIELD = "не пусте поле";
        #endregion

        #region Readonly & Static Fields
        private static readonly CsvMappedProperty[] _csvMappedProperties;
        #endregion

        #region C'tors
        static FinancistoExpense()
        {
            CustomList<string> colNamesDate = new CustomList<string>(new[] {"date"});
            CustomList<string> colNamesTime = new CustomList<string>(new[] {"time"});
            CustomList<string> colNamesAccount = new CustomList<string>(new[] {"account"});
            CustomList<string> colNamesAmount = new CustomList<string>(new[] {"amount"});
            CustomList<string> colNamesCurrency = new CustomList<string>(new[] {"currency"});
            CustomList<string> colNamesCategory = new CustomList<string>(new[] {"category"});
            CustomList<string> colNamesParent = new CustomList<string>(new[] {"parent"});
            CustomList<string> colNamesProject = new CustomList<string>(new[] {"project"});
            CustomList<string> colNamesNote = new CustomList<string>(new[] {"note"});

            Type t = typeof(FinancistoExpense);

            _csvMappedProperties = new[]
                {
                    new CsvMappedProperty(t.GetProperty("Date"), colNamesDate, null,
                        new[]
                            {
                                new EasyRegularExpressionValidator(RegularExpressionPatterns.NonEmptyString,
                                    string.Format(MESSAGE_TEMPLATE, colNamesDate.ItemsToString(", "),
                                        NON_EMPTY_FIELD))
                            },
                        DateTimeFromStringConverter.DefaultInstance, null),
                    new CsvMappedProperty(t.GetProperty("Time"), colNamesTime, null,
                        new[]
                            {
                                new EasyRegularExpressionValidator(RegularExpressionPatterns.NonEmptyString,
                                    string.Format(MESSAGE_TEMPLATE, colNamesTime.ItemsToString(", "),
                                        NON_EMPTY_FIELD))
                            },
                        DateTimeFromStringConverter.DefaultInstance, null),
                    new CsvMappedProperty(t.GetProperty("Account"), colNamesAccount, null,
                        new[]
                            {
                                new EasyRegularExpressionValidator(RegularExpressionPatterns.NonEmptyString,
                                    string.Format(MESSAGE_TEMPLATE, colNamesAccount.ItemsToString(", "),
                                        NON_EMPTY_FIELD))
                            },
                        IdleFromStringConverter.Instance, null),
                    new CsvMappedProperty(t.GetProperty("Amount"), colNamesAmount, null,
                        new[]
                            {
                                new EasyRegularExpressionValidator(RegularExpressionPatterns.NonEmptyString,
                                    string.Format(MESSAGE_TEMPLATE, colNamesAmount.ItemsToString(", "),
                                        NON_EMPTY_FIELD))
                            },
                        new FinancistoDecimalFromStringConverter(), null),
                    new CsvMappedProperty(t.GetProperty("Currency"), colNamesCurrency, null,
                        new[]
                            {
                                new EasyRegularExpressionValidator(RegularExpressionPatterns.NonEmptyString,
                                    string.Format(MESSAGE_TEMPLATE, colNamesCurrency.ItemsToString(", "),
                                        NON_EMPTY_FIELD))
                            },
                        IdleFromStringConverter.Instance, null),
                    new CsvMappedProperty(t.GetProperty("Category"), colNamesCategory, null, null,
                        IdleFromStringConverter.Instance, null),
                    new CsvMappedProperty(t.GetProperty("Parent"), colNamesParent, null, null,
                        IdleFromStringConverter.Instance, null),
                    new CsvMappedProperty(t.GetProperty("Project"), colNamesProject, null,
                        new[]
                            {
                                new EasyRegularExpressionValidator(RegularExpressionPatterns.NonEmptyString,
                                    string.Format(MESSAGE_TEMPLATE, colNamesProject.ItemsToString(", "),
                                        NON_EMPTY_FIELD))
                            },
                        IdleFromStringConverter.Instance, null),
                    new CsvMappedProperty(t.GetProperty("Note"), colNamesNote, null, null,
                        IdleFromStringConverter.Instance, null)
                };
        }

        public FinancistoExpense()
        {
            ImportStatuses = new List<ImportStatus>();
        }
        #endregion

        #region Instance Properties
        [Required]
        public virtual FinancistoFile FinancistoFile { get; set; }

        public string Parent { get; set; }
        public DateTime Time { get; set; }
        #endregion

        #region ICommonExpense Members
        public string Account { get; set; }

        public decimal Amount { get; set; }

        public string Category { get; set; }
        public string Currency { get; set; }
        public string Note { get; set; }
        public string Project { get; set; }

        DateTime ICommonExpense.Date
        {
            get { return Date.Date.AddHours(Time.Hour).AddMinutes(Time.Minute).AddSeconds(Time.Second); }
            set
            {
                Date = value.Date;
                Time = value.Date;
            }
        }
        #endregion

        #region ICsvEntity Members
        public IEnumerable<CsvMappedProperty> GetMappedProperties()
        {
            return _csvMappedProperties;
        }
        #endregion

        #region IImportedEntity Members
        string IImportedEntity.Type
        {
            get { return Project; }
            set { Project = value; }
        }

        public DateTime Date { get; set; }

        public bool Processed { get; set; }

        public virtual ICollection<ImportStatus> ImportStatuses { get; set; }

        public UserDependedImportedFile UserDependedImportedFile
        {
            get { return FinancistoFile; }
        }
        #endregion

        #region Class Methods
        public static void ResetMappedProperties()
        {
            foreach (CsvMappedProperty csvMappedProperty in _csvMappedProperties)
            {
                csvMappedProperty.ColumnNames.Reset();
            }
        }
        #endregion
    }
}